
include std/unittest.e
include std/sequence.e
include std/text.e
include std/sort.e
include std/math.e
include qt/debug_utils.e
include qt/permcomb.e
include qt/trigmath.e

object _ = 0


sequence result = {{},{}}


--good news: select_qrs & gsl_combination are identical to 5
-- will have to wait for more gsl wrapping to get higher numbers.
--bad news: you have to decipher the following loops
for i = 3 to length(combsu) do
  for j = 1 to length(combsu[i])-1 do  -- 
 result = {{},{}}
      --~ printf(1, "\n%dx%d %dx%d   [%s]\n", { --
           --~ i,j+1
           --~ ,combsu[i][j][1], combsu[i][j][2]
       --~ ,sprintf("%s", {itoa( join(combsu[i][$][3][1] ,""), 16 )})
        --~ })
       for k = 1 to length(combsu[i][j][3]) do
          --~ printf(1, "%s  ", { --
             --~ itoa( join(combsu[i][j][3][k] ,""), 16 )
          --~ })
          --~ result[1] &= {combsu[i][j][3][k] }  -- &{1} to see fail tests
           result[1] = append(result[1], combsu[i][j][3][k] )
          --~ result[2] &= 
                     --~ { select_qrs(k, combsu[i][j][2]
                           --~ ,combsu[i][$][3][1] ) }  -- 1,,l seq is @$
           result[2] = append(result[2], 
                      select_qrs(k, combsu[i][j][2]
                              ,combsu[i][$][3][1] ) 
                      )
      end for
          --no sort required
          --~ result[1] = sort(result[1])
          --~ result[2] = sort(result[2])
      test_equal("select_qrs(1..q,"  &sprint(j+1)&"  "&sprintf(",%s ) ", {itoa( join(combsu[i][$][3][1] ,""), 16 )})
          ,result[1]
           ,result[2] )
      test_equal("nCr(" &sprint(i)&sprint(j)
          ,length(combsu[i][j][3])
           ,nCr(i, j+1) )  -- j is lagging because of base0/1 differences
  end for
end for
  
--test perms 2..6
--perms sequence is a little simpler but way larger after 5
for i = 2 to length(permsu) do
    result = {{},{}}
      --~ printf(1, "\n%dx %d \n", { --
           --~ i, permsu[i][1]
        --~ })

      --~ result[1] &= permsu[i][2] -- &{1} to see fail tests, comment out permsu>4 first!
        result[1] = permsu[i][2]
       for k = 1 to length(permsu[i][2]) do
          --~ result[2] &= 
                     --~ { perm_qrs(k, permsu[i][1]
                           --~ ,permsu[i][2][1] ) }  -- use the first perm
          result[2] = append(result[2], 
                      perm_qrs(k, permsu[i][1]
                           ,permsu[i][2][1] ) 
                    )
       end for
          --no sort required
          --~ result[1] = sort(result[1])
          --~ result[2] = sort(result[2])
      test_equal("perm_qrs(1..q,"  &sprint(i) &" {0..i}"
          ,result[1]
           ,result[2] )
      test_equal("nPr(" &sprint(i)&sprint(permsu[i][1]) -- =ixi
          ,length(permsu[i][2])
           ,nPr(i, i ) )
end for

 
    test_equal("nCr(3, 3)", 1 ,nCr(3, 3))
    test_equal("nCr(3, 2)", 3 ,nCr(3, 2))
    test_equal("nPr(3, 2)", 5 ,nPr(3, 2))
    test_equal("nPr(2, 2)", 2 ,nPr(2, 2))
    test_equal("nPr(3, 3)", 6 ,nPr(3, 3))
    test_equal(",nD(6)", 265 ,nD(6))

   bfi:set_places(0)
    test_equal("bignCr(49,6)", "13983816" ,num_text(bignCr(49,6)) )
    --~ test_equal("bignCr(35,10)", 183579396 ,bignCr(35,10))

    test_equal("nPr(10,4)", 5040 ,nPr(10,4))  --wrong?
    --~ failed: nPr(10,4), expected: 5040 but got: 3628080
    --possibly the drmath calc is using repititions and we aren't?
    test_equal("perm_n_by_r(10,4)", 5040 ,perm_n_by_r(10,4))

    test_equal("bignPr(10,4)", "5040" ,num_text(bignPr(10,4)) )


    --~ test_equal("bignPCr(10,4)", 12350 ,bignPCr(10,4))

    --~ test_equal("Pk(4)", 15 ,Pk(4))
--~ there are 15 partitions of a set of 4 objects

    test_equal("bigfactorial(6)", "720"
                  ,num_text(bigfactorial(6)))
    test_equal("bigfactorial(27)", "10888869450418352160768000000"
                        , num_text(bigfactorial(27)))
    test_equal("bigfactorial(29)", "8841761993739701954543616000000"
                        , num_text(bigfactorial(29)))
    test_equal("bigfactorial(30)", "265252859812191058636308480000000"
                        , num_text(bigfactorial(30)))
    test_equal("bigfib(25)", "75025"
                        , num_text(bigfib(25)))

    test_equal("bigfib(31)", "1346269"
                        , num_text(bigfib(31)))

    --~ test_equal("fib(31)", 1346269
                        --~ , fib(31))
    --~ test_equal("fib(35)", 9227465
                        --~ , fib(35))

    test_equal("bigfib(35)", "9227465"
                        ,num_text(bigfib(35)))

    test_equal("bigfib(70)", "308061521170129"
                        ,num_text(bigfib(71)))

    --~ test_equal("bigfib(1000)", "43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875"
                        --~ ,num_text(bigfib(1000)))



   --from docs
     test_equal("1","acbd"  ,perm_qs(3,"abcd"))
     test_equal("2", "bde" ,select_qrs(19,3,"abcde"))
     test_equal("3", "cad" ,perm_qrs(15,3,"abcd"))

--test for permcomb.e docs eucode  example
 sequence word = ""
 sequence letters="ABC"
	for q=1 to  nPr(3,2) do
		word &= perm_qrs( q, 2, letters )
	end for
 -- printf(1, "%s\n", {word})
-- --ABBAACCAAB
    test_equal("word 1..perm"
                ,"ABBAACCAAB"
               ,word )


sequence t
sequence should_be =  --more accuratly hopes_is
             {"ABC", "ACB", "BAC", "BCA", "CAB","CBA"}

letters = "ABC"
result = {}
integer	perms
     ,r = 3

     perms = nPr(length(letters), r)
     for q=1 to perms do
          result &= {perm_qs(q, letters) }
     end for
    test_equal("perm_qs 1..perm",
                should_be 
               ,result )


 should_be = {
   "AB", "BA", "AC", "CA", "BC", "CB"
      }
letters = "ABC"
result = {}
r = 2
  for j = 1 to nCr(length(letters), r) do
    t = select_qrs(j, r, letters)
    for k = 1 to nPr(length(t), r) do --1..length(t) not enough
        --~ result &= {perm_qrs(k, r, t)}  --
        result = append(result, perm_qrs(k, r, t) )
    end for
  end for
    test_equal("perm_qs 2",
          should_be
         ,result )

  

--~ c = probstat.Combination(range(1,5),3) ignores 5?
  r=3
 should_be = {
   {1,2,3},  {1,2,4},  {1,2,5},
  {1,3,4},  {1,3,5},
  {1,4,5},
  {2,3,4},  {2,3,5},
  {2,4,5},
 {3,4,5}
 }
letters = {1,2,3,4,5}
result = {}
  for j = 1 to nCr(length(letters), r) do
    t = select_qrs(j, r, letters)
        result &= {t}  --

  end for
    test_equal("select_qrs ",
             should_be
               ,result )


  r=2
 should_be = {
  --~ "DD", "CD", "BD", "AD", "DC", "CC", "BC", "AC",  --with repititions
  --~ "DB", "CB", "BB", "AB", "DA", "CA", "BA", "AA"
  "AB",  "BA",  "AC",  "CA",  "AD",  "DA",  "BC",
  "CB",  "BD",  "DB",  "CD",  "DC"
 }
letters = {'A','B','C','D'}
result = {}
  for j = 1 to nCr(length(letters), r) do
    t = select_qrs(j, r, letters)
    for k = 1 to nPr(length(t), r) do --1..length(t) not enough
        result &= {perm_qs(k, t)}
    end for

  end for
    test_equal("select_qrs perm_qs {'A','B','C','D'}",
             should_be
               ,result )



--~ 
  r=3
 should_be = {
    --~ "BCD", "ACD", "ABD", "ABC"  --is there a prefered ordering?
     "ABC", "ABD", "ACD", "BCD" --reverse of expected should be tested
  }
letters = "ABCD"
result = {}
  for j = 1 to nCr(length(letters), r) do
    t = select_qrs(j, r, letters)
        result &= {t}  --
   end for
    test_equal("select_qrs ABCD",
             should_be
               ,result )


--~ 
  r=2
 should_be = {
   --~ {1,1},{1,2},{1,3},{2,1},{2,2},{2,3},{3,1},{3,2},{3,3} --w/r
  {1,2}, {2,1}, {1,3}, {3,1}, {2,3}, {3,2}  -- w/o repitions
 }
letters = {1,2,3}
result = {}
  for j = 1 to nCr(length(letters), r) do
    t = select_qrs(j, r, letters)
    for k = 1 to nPr(length(t), r) do --1..length(t) not enough
        result &= {perm_qrs(k, r, t)}
    end for

  end for
    test_equal("select_qrs perm_qrs{1,2,3}",
             should_be
               ,result )
  


 --seems like it's just repeating 3 times?
  r=3
 should_be = {
  {1,0,3},  {1,3,0},  {0,1,3}, {0,3,1}, {3,1,0},  {3,0,1}
 }
letters = {1,0,3}
result = permcombs(letters, r, 0 )
    test_equal("permcombs "&sprint(letters)&sprint(r),
             should_be
               ,result )


  --why perm returns atoms when called with char
  --but char passed to selection passed to perm returns strings?

  --why is it called select instead of combinations?

--, too many bad results make it hard to work on
test_equal("some repeats left in so tests pass",{}, 1)
test_equal("obviously this should be fixed",{}, 1)

--ne1 11/09
--are there any math majors in the audiance?
--it may be some inexact results are a tradeoff for speed?
--more likely flawed tests.


test_report()

